Djangoć§ć«ć¹ćæć ć¦ć¼ć¶ć¼ć¢ćć«ćå®č£ ććå¤ę§ćŖć°ćć¼ćć«ć¢ććŖć±ć¼ć·ć§ć³ć®č¦ä»¶ć«åććć¦čŖčؼćå¼·åććććć®å ę¬ēćŖć¬ć¤ćććć¹ććć©ćÆćć£ć¹ćØé«åŗ¦ćŖććÆćććÆćå¦ć³ć¾ćć
Python DjangočŖčؼļ¼ć°ćć¼ćć«ć¢ććŖć±ć¼ć·ć§ć³åćć«ć¹ćæć ć¦ć¼ć¶ć¼ć¢ćć«ć®ēæå¾
Djangoć®ēµćæč¾¼ćæčŖčؼć·ć¹ćć ćÆćå¤ćć®Webć¢ććŖć±ć¼ć·ć§ć³ć«ćØć£ć¦å¼·åćŖåŗēŗē¹ćØćŖćć¾ćććć ććć¢ććŖć±ć¼ć·ć§ć³ćć¹ć±ć¼ć«ć¢ććććē¹ć«ć°ćć¼ćć«ćŖć¦ć¼ć¶ć¼ć対豔ćØććå “åć«č¤éć«ćŖćć«ć¤ćć¦ćććć©ć«ćć®Userć¢ćć«ć§ćÆäøååć«ćŖćåÆč½ę§ćććć¾ććććć§ć«ć¹ćæć ć¦ć¼ć¶ć¼ć¢ćć«ćē»å “ććć¦ć¼ć¶ć¼ćć¼ćæćØčŖčؼććć»ć¹ćććęč»ć«å¶å¾”ć§ććććć«ćŖćć¾ćććć®å ę¬ēćŖć¬ć¤ćć§ćÆćDjangoć§ć«ć¹ćæć ć¦ć¼ć¶ć¼ć¢ćć«ćä½ęććć³å®č£ ććććć»ć¹ćčŖ¬ęććć¢ććŖć±ć¼ć·ć§ć³ćå¤ę§ćŖć¦ć¼ć¶ć¼č¦ä»¶ćØć»ćć„ćŖćć£ć®čę ®äŗé ć«åƾåæć§ććććć«ćć¾ćć
ć«ć¹ćæć ć¦ć¼ć¶ć¼ć¢ćć«ć使ēØććēē±
ććć©ć«ćć®Django Userć¢ćć«ćÆćusernamećpasswordćemailćfirst_namećlast_namećŖć©ć®äøč¬ēćŖå±ę§ć§čØčØććć¦ćć¾ććåē“ćŖć¢ććŖć±ć¼ć·ć§ć³ć«ćÆé©ćć¦ćć¾ćććꬔć®ćććŖå “åć«ćÆäøååć«ćŖćććØćććććć¾ćć
- čæ½å ć®ć¦ć¼ć¶ć¼ę å ±ćäæåććļ¼ ć¦ć¼ć¶ć¼ć®å„½ćæććć¾ćć¾ćŖå½¢å¼ć®ć¢ćć¬ć¹ćåŖå é貨ćć¾ććÆčØčŖčØå®ćäæåććåæ č¦ćććć°ćć¼ćć«eć³ćć¼ć¹ćć©ćććć©ć¼ć ćę¤čØćć¦ćć ćććććććÆććć©ć«ćć®ć¢ćć«ć®ēÆå²ćč¶ ćć¦ćć¾ćć
- čŖčؼćć£ć¼ć«ććå¤ę“ććļ¼ usernameć®ä»£ććć«ć”ć¼ć«ć¢ćć¬ć¹ć使ēØćć¦ć¦ć¼ć¶ć¼ćčŖčؼććććčæ½å ć®ćć£ć¼ć«ććåæ č¦ćØććå¤č¦ē“ čŖčؼćå®č£ ćććććå “åćŖć©ćććć¾ćć
- ę¢åć®ćć¼ćæćć¼ć¹ćØēµ±åććļ¼ Djangoć¢ććŖć±ć¼ć·ć§ć³ććē°ćŖćć¦ć¼ć¶ć¼Schemaćęć¤ę¢åć®ćć¼ćæćć¼ć¹ćØēµ±åććå “åćć«ć¹ćæć ć¦ć¼ć¶ć¼ć¢ćć«ć使ēØćććØćć¢ćć«ćę¢åć®ćć¼ćæę§é ć«ćććć³ć°ć§ćć¾ćć
- ć»ćć„ćŖćć£ćå¼·åććļ¼ ć«ć¹ćæć ć¢ćć«ć使ēØćććØććć¹ćÆć¼ćć®ććć·ć„åććć¹ćÆć¼ćć®ćŖć»ććć”ć«ććŗć ćććć³ćć®ä»ć®ć»ćć„ćŖćć£é¢é£ć®å“é¢ćććē“°ććå¶å¾”ć§ćć¾ćć
- ē°ćŖćć¦ć¼ć¶ć¼ćć¼ć«ćå®č£ ććļ¼ ćć¼ć«ćć¼ć¹ć®ć¢ćÆć»ć¹å¶å¾”ļ¼RBACļ¼ćć¼ćæćć¢ćć«ć«ē“ę„äæåļ¼ć¾ććÆåē §ļ¼ćććØćę±ēØēćŖć°ć«ć¼ćć権éćććęč»ć§ę示ēćŖå¶å¾”ćåÆč½ć«ćŖćć¾ćć
ć«ć¹ćæć ć¦ć¼ć¶ć¼ć¢ćć«ć使ēØćććØćć³ć¢DjangočŖčؼć·ć¹ćć ćē“ę„å¤ę“ććć«ćć¦ć¼ć¶ć¼ćććć”ć¤ć«ćę”å¼µććććć®ćÆćŖć¼ć³ć§äæå®åÆč½ćŖę¹ę³ćęä¾ććć¾ććå°ę„ć®ęé·ćč¦č¾¼ć¾ćććććøć§ćÆćććē¹ę®ćŖć¦ć¼ć¶ć¼ćć¼ćæćåæ č¦ćØćććććøć§ćÆćć«ćØć£ć¦ććć¹ććć©ćÆćć£ć¹ć§ćć
ć«ć¹ćæć ć¦ć¼ć¶ć¼ć¢ćć«ćå®č£ ććęę
ć«ć¹ćæć ć¦ć¼ć¶ć¼ć¢ćć«ćå®č£ ććęé©ćŖćæć¤ćć³ć°ćÆććććøć§ćÆćć®éå§ęć§ććę¬ēŖē°å¢ć§ć¦ć¼ć¶ć¼ć¢ćć«ćå¤ę“ćććØćč¤éć«ćŖćććć¼ćæćē “ęććåÆč½ę§ćććć¾ćććććøć§ćÆćććć§ć«é²č”äøć®å “åćÆćå¤ę“ćå ććåć«ćå½±éæćę éć«ę¤čØććå ē¢ćŖē§»č”čØē»ćä½ęćć¦ćć ććć
äøč¬ēćŖć¬ć¤ćć©ć¤ć³ćꬔć«ē¤ŗćć¾ćć
- ć«ć¹ćæć ć¦ć¼ć¶ć¼ć¢ćć«ććéå§ććļ¼ ę”å¼µćććć¦ć¼ć¶ć¼ę å ±ć¾ććÆć«ć¹ćæć čŖčؼććøććÆćåæ č¦ć«ćŖććØäŗę³ćććå “åć
- ē§»č”ćę éć«ę¤čØććļ¼ ć¦ć¼ć¶ć¼ćććå®č”äøć®Djangoćććøć§ćÆćććć§ć«ćććć«ć¹ćæć ć¢ćć«ć«åćęæććććØć«ććå “åććć¼ćæćć¼ć¹ććććÆć¢ććććē§»č”ććć»ć¹ćå®å Øć«ēč§£ćć¦ćć ććć
ć«ć¹ćæć ć¦ć¼ć¶ć¼ć¢ćć«ć®ä½ę
Djangoć§ć«ć¹ćæć ć¦ć¼ć¶ć¼ć¢ćć«ćä½ęććć«ćÆćäø»ć«2ć¤ć®ę¹ę³ćććć¾ćć
- AbstractBaseUserļ¼ ćć®ę¹ę³ć§ćÆćć¦ć¼ć¶ć¼ć¢ćć«ćå®å Øć«å¶å¾”ć§ćć¾ććusernamećpasswordćemailćåæ č¦ćŖć«ć¹ćæć ćć£ć¼ć«ććŖć©ććć¹ć¦ć®ćć£ć¼ć«ććå®ē¾©ćć¾ćć
- AbstractUserļ¼ ćć®ę¹ę³ćÆćććć©ć«ćć®Django Userć¢ćć«ććē¶ęæććę¢åć®ćć£ć¼ć«ććčæ½å ć¾ććÆćŖć¼ćć¼ć©ć¤ćć§ćć¾ććčæ½å ćććć£ć¼ć«ććććć¤ććććŖćå “åćÆććććććē°”åć§ćć
1. AbstractBaseUserć®ä½æēØļ¼å®å ØćŖå¶å¾”ļ¼
ćććÆęćęč»ćŖćŖćć·ć§ć³ć§ćććć¦ć¼ć¶ć¼ć¢ćć«å Øä½ćęåććå®ē¾©ć§ćć¾ććć¦ć¼ć¶ć¼ćć¼ćæę§é ćØčŖčؼććć»ć¹ćęćē“°ććå¶å¾”ć§ćć¾ććę¹ę³ćÆę¬”ć®ćØććć§ćć
ć¹ććć1ļ¼ć«ć¹ćæć ć¦ć¼ć¶ć¼ć¢ćć«ć®ä½ę
Djangoć¢ććŖļ¼ä¾ļ¼ćaccountsćļ¼ć§ć`models.py`ćć”ć¤ć«ćä½ęćć`AbstractBaseUser`ććć³`PermissionsMixin`ććē¶ęæććć«ć¹ćæć ć¦ć¼ć¶ć¼ć¢ćć«ćå®ē¾©ćć¾ćć
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager
class CustomUserManager(BaseUserManager):
def create_user(self, email, password=None, **extra_fields):
if not email:
raise ValueError('The Email field must be set')
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, password, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
extra_fields.setdefault('is_active', True)
if extra_fields.get('is_staff') is not True:
raise ValueError('Superuser must have is_staff=True.')
if extra_fields.get('is_superuser') is not True:
raise ValueError('Superuser must have is_superuser=True.')
return self.create_user(email, password, **extra_fields)
class CustomUser(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True, verbose_name='email address')
first_name = models.CharField(max_length=150, blank=True)
last_name = models.CharField(max_length=150, blank=True)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
date_joined = models.DateTimeField(auto_now_add=True)
# Custom fields (Example: preferred language, timezone, etc.)
preferred_language = models.CharField(max_length=10, default='en', choices=[('en', 'English'), ('fr', 'French'), ('es', 'Spanish')])
timezone = models.CharField(max_length=50, default='UTC')
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = [] # Required when creating a superuser
objects = CustomUserManager()
def __str__(self):
return self.email
čŖ¬ęļ¼
- CustomUserManagerļ¼ ćć®ćÆć©ć¹ćÆćć«ć¹ćæć ć¦ć¼ć¶ć¼ć¢ćć«ćē®”ēććććć«åæ č¦ć§ććć¦ć¼ć¶ć¼ćØć¹ć¼ćć¼ć¦ć¼ć¶ć¼ć®ä½ęćå¦ēćć¾ćć `normalize_email`ćÆćē°ćŖććć±ć¼ć«ććć³å „åę¹ę³å Øä½ć§ć”ć¼ć«ć®äøč²«ę§ć確äæććććć«éč¦ć§ćć
- CustomUserļ¼ ćććÆć«ć¹ćæć ć¦ć¼ć¶ć¼ć¢ćć«ć§ćć
- `email = models.EmailField(unique=True, verbose_name='email address')`ļ¼ć¦ć¼ć¶ć¼ć®äøęć®čå„åćØćć¦ć”ć¼ć«ćć£ć¼ć«ććå®ē¾©ćć¾ćć `unique=True`ć使ēØćććØćåć¦ć¼ć¶ć¼ćäøęć®ć”ć¼ć«ć¢ćć¬ć¹ćęć¤ććØćäæčؼććć¾ćć verbose_namećÆē®”ēć¤ć³ćæć¼ćć§ć¼ć¹ćę¹åćć¾ćć
- `first_name`ć`last_name`ļ¼ć¦ć¼ć¶ć¼ć®ååćäæåććććć®ęØęŗćć£ć¼ć«ćć `blank=True`ć使ēØćććØććććć®ćć£ć¼ć«ćć空ć«ććććØćć§ćć¾ćć
- `is_staff`ć`is_active`ļ¼ē®”ēććć«ćøć®ć¦ć¼ć¶ć¼ć¢ćÆć»ć¹ćØć¢ć«ć¦ć³ćć®ć¢ćÆćć£ćåćå¶å¾”ććććć®ęØęŗćć£ć¼ć«ćć
- `date_joined`ļ¼ć¦ć¼ć¶ć¼ć¢ć«ć¦ć³ććä½ęćććę„ä»ćčØé²ćć¾ćć
- `preferred_language`ć`timezone`ļ¼ć¦ć¼ć¶ć¼ć®å„½ćæćäæåććć«ć¹ćæć ćć£ć¼ć«ćć®ä¾ć `choices`å¼ę°ćÆćåÆč½ćŖčØčŖćŖćć·ć§ć³ćå¶éćć¾ćććććÆć°ćć¼ćć«ć¢ććŖć±ć¼ć·ć§ć³ć«ćØć£ć¦éåøøć«éč¦ć§ćććæć¤ć ć¾ć¼ć³ććć¼ć«ćŖć¼ć¼ć·ć§ć³ć«ćØć£ć¦éč¦ć§ćć
- `USERNAME_FIELD = 'email'`ļ¼čŖčؼć«ć¦ć¼ć¶ć¼åćØćć¦ć”ć¼ć«ćć£ć¼ć«ćć使ēØććććØćęå®ćć¾ćć
- `REQUIRED_FIELDS = []`ļ¼`createsuperuser`ć³ćć³ćć使ēØćć¦ć¹ć¼ćć¼ć¦ć¼ć¶ć¼ćä½ęćććØćć«åæ č¦ćŖćć£ć¼ć«ććęå®ćć¾ćććć®å “åćć”ć¼ć«ćØćć¹ćÆć¼ćć«å ćć¦ćčæ½å ć®ćć£ć¼ć«ććÆåæ č¦ććć¾ććć
- `objects = CustomUserManager()`ļ¼ć«ć¹ćæć ć¦ć¼ć¶ć¼ććć¼ćøć£ć¼ćć¢ćć«ć«å²ćå½ć¦ć¾ćć
- `__str__(self)`ļ¼ć¦ć¼ć¶ć¼ćŖććøć§ćÆććęååćØćć¦ć©ć®ććć«č”Øē¾ćććććå®ē¾©ćć¾ćļ¼ä¾ļ¼ē®”ēććć«å ļ¼ć
ć¹ććć2ļ¼`settings.py`ć®ę“ę°
`settings.py`ćć”ć¤ć«ć«ę¬”ć®č”ćčæ½å ćć¦ćDjangoć«ć«ć¹ćæć ć¦ć¼ć¶ć¼ć¢ćć«ć使ēØććććć«ę示ćć¾ćć
AUTH_USER_MODEL = 'accounts.CustomUser'
`accounts`ćć`CustomUser`ć¢ćć«ćå®ē¾©ććć¢ććŖć®ååć«ē½®ćęćć¾ćć
ć¹ććć3ļ¼ē§»č”ć®ä½ęćØé©ēØ
ꬔć®ć³ćć³ććå®č”ćć¦ćē§»č”ćä½ęćć¦é©ēØćć¾ćć
python manage.py makemigrations
python manage.py migrate
ććć«ćććć«ć¹ćæć ć¦ć¼ć¶ć¼ć¢ćć«ć®ę°ćććć¼ćæćć¼ć¹ćć¼ćć«ćä½ęććć¾ćć
ć¹ććć4ļ¼ć«ć¹ćæć ć¦ć¼ć¶ć¼ć¢ćć«ć®ä½æēØ
ććć§ććć„ć¼ććć³ćć¬ć¼ććććć³ć¢ććŖć±ć¼ć·ć§ć³ć®ä»ć®éØåć§ć«ć¹ćæć ć¦ć¼ć¶ć¼ć¢ćć«ć使ēØć§ćć¾ććććØćć°ćę°ććć¦ć¼ć¶ć¼ćä½ęććć«ćÆćꬔć®ććć«ćŖćć¾ćć
from accounts.models import CustomUser
user = CustomUser.objects.create_user(email='user@example.com', password='password123', first_name='John', last_name='Doe')
2. AbstractUserć®ä½æēØļ¼ććć©ć«ćć¢ćć«ćøć®čæ½å ļ¼
ććć©ć«ćć®Django Userć¢ćć«ć«ććć¤ćć®ćć£ć¼ć«ććčæ½å ććć ćć§ććå “åćÆććć®ę¹ę³ćććē°”åć§ćć `AbstractUser`ććę¢åć®ćć¹ć¦ć®ćć£ć¼ć«ććØć”ć½ćććē¶ęæćć¾ćććććÆćććē°”åćŖć«ć¹ćæćć¤ćŗć«å½¹ē«ć”ć¾ćć
ć¹ććć1ļ¼ć«ć¹ćæć ć¦ć¼ć¶ć¼ć¢ćć«ć®ä½ę
Djangoć¢ććŖć®`models.py`ćć”ć¤ć«ć§ć`AbstractUser`ććē¶ęæććć«ć¹ćæć ć¦ć¼ć¶ć¼ć¢ćć«ćå®ē¾©ćć¾ćć
from django.contrib.auth.models import AbstractUser
from django.db import models
class CustomUser(AbstractUser):
# Add extra fields here
phone_number = models.CharField(max_length=20, blank=True, verbose_name='Phone Number')
profile_picture = models.ImageField(upload_to='profile_pictures/', blank=True)
# Custom fields (Example: preferred currency, address format, etc.)
preferred_currency = models.CharField(max_length=3, default='USD', choices=[('USD', 'US Dollar'), ('EUR', 'Euro'), ('JPY', 'Japanese Yen')])
address_format = models.CharField(max_length=50, blank=True, help_text='e.g., "Name, Street, City, Zip, Country"')
def __str__(self):
return self.username
čŖ¬ęļ¼
- CustomUserļ¼ ćććÆć`AbstractUser`ććē¶ęæććć«ć¹ćæć ć¦ć¼ć¶ć¼ć¢ćć«ć§ćć
- `phone_number`ć`profile_picture`ļ¼ć¦ć¼ć¶ć¼ć¢ćć«ć«čæ½å ćććć£ć¼ć«ćć®ä¾ć `upload_to`ćÆććććć£ć¼ć«åēćäæåćććå “ęćęå®ćć¾ćć
- `preferred_currency`ć`address_format`ļ¼ć°ćć¼ćć«ć¢ććŖć±ć¼ć·ć§ć³ć«é¢é£ććć«ć¹ćæć ćć£ć¼ć«ćć®ä¾ćå½ć«ćć£ć¦ć¢ćć¬ć¹å½¢å¼ć大ććē°ćŖćć¾ćć
- `__str__(self)`ļ¼ć¦ć¼ć¶ć¼ćŖććøć§ćÆććęååćØćć¦ć©ć®ććć«č”Øē¾ćććććå®ē¾©ćć¾ćļ¼ä¾ļ¼ē®”ēććć«å ļ¼ćććć§ćÆćusernameć使ēØćć¾ćć
ć¹ććć2ļ¼`settings.py`ć®ę“ę°
仄åćØåę§ć«ć`settings.py`ćć”ć¤ć«ć«ę¬”ć®č”ćčæ½å ćć¦ćDjangoć«ć«ć¹ćæć ć¦ć¼ć¶ć¼ć¢ćć«ć使ēØććććć«ę示ćć¾ćć
AUTH_USER_MODEL = 'accounts.CustomUser'
ć¹ććć3ļ¼ē§»č”ć®ä½ęćØé©ēØ
ꬔć®ć³ćć³ććå®č”ćć¦ćē§»č”ćä½ęćć¦é©ēØćć¾ćć
python manage.py makemigrations
python manage.py migrate
ć¹ććć4ļ¼ć«ć¹ćæć ć¦ć¼ć¶ć¼ć¢ćć«ć®ä½æēØ
ć¦ć¼ć¶ć¼ćŖććøć§ćÆććęä½ćććØćć«ćčæ½å ććććć£ć¼ć«ćć«ć¢ćÆć»ć¹ć§ććććć«ćŖćć¾ććć
from accounts.models import CustomUser
user = CustomUser.objects.create_user(username='johndoe', password='password123', email='john.doe@example.com')
user.phone_number = '+15551234567'
user.preferred_currency = 'EUR'
user.save()
ć°ćć¼ćć«ć¢ććŖć±ć¼ć·ć§ć³ć«ćććć«ć¹ćæć ć¦ć¼ć¶ć¼ć¢ćć«ć®ćć¹ććć©ćÆćć£ć¹
ć°ćć¼ćć«ć¦ć¼ć¶ć¼ć対豔ćØććć¢ććŖć±ć¼ć·ć§ć³ć«ć«ć¹ćæć ć¦ć¼ć¶ć¼ć¢ćć«ćå®č£ ććå “åćÆćꬔć®ćć¹ććć©ćÆćć£ć¹ćę¤čØćć¦ćć ććć
1. å½éåćØćć¼ć«ćŖć¼ć¼ć·ć§ć³ļ¼i18nļ¼l10nļ¼
ćć±ć¼ć«åŗęć®ćć¼ćæćäæåććļ¼ ćć¾ćć¾ćŖęåč¦ēÆćØćć¼ćæå½¢å¼ć«åƾåæććććć«ć¢ćć«ćčØčØćć¾ććę„ä»ćęå»ćę°å¤ćććć³ć¢ćć¬ć¹ććć±ć¼ć«åƾåæć®ę¹ę³ć§äæåćć¾ćć
ä¾ļ¼
from django.utils import timezone
class CustomUser(AbstractUser):
#...
date_of_birth = models.DateField(blank=True, null=True)
def get_localized_date_of_birth(self, language_code):
if self.date_of_birth:
return timezone.localtime(timezone.make_aware(datetime.datetime.combine(self.date_of_birth, datetime.time.min))).strftime('%x') # Format according to the locale
return None
2. ćæć¤ć ć¾ć¼ć³ć®å¦ē
åøøć«ćæć¤ć ć¾ć¼ć³ćę£ććäæåćć¦å¦ēćć¾ćććæć¤ć ć¾ć¼ć³ę å ±ćć¦ć¼ć¶ć¼ć¢ćć«ć«äæåććććć使ēØćć¦ę„ä»ćØęå»ćć¦ć¼ć¶ć¼ć®ćć¼ć«ć«ćæć¤ć ć¾ć¼ć³ć§č”Øē¤ŗćć¾ćć
ä¾ļ¼
from django.utils import timezone
class CustomUser(AbstractUser):
#...
timezone = models.CharField(max_length=50, default='UTC')
def get_localized_time(self, datetime_obj):
user_timezone = pytz.timezone(self.timezone)
return timezone.localtime(datetime_obj, user_timezone)
3. ć¢ćć¬ć¹ć®ęøå¼čØå®
ć¢ćć¬ć¹ć®ęøå¼ćÆå½ć«ćć£ć¦å¤§ććē°ćŖćć¾ććć¦ć¼ć¶ć¼ćčŖåć®å “ęć«åććć¦ę£ććå½¢å¼ć§ć¢ćć¬ć¹ćå „åć§ććęč»ćŖć¢ćć¬ć¹ć·ć¹ćć ćå®č£ ćć¾ćććµć¼ććć¼ćć£ć®ć©ć¤ćć©ćŖć¾ććÆćµć¼ćć¹ć使ēØćć¦ćć¢ćć¬ć¹ć®ę¤čؼćØęøå¼čØå®ćå¦ēććććØćę¤čØćć¦ćć ććć
ä¾ļ¼
class CustomUser(AbstractUser):
#...
country = models.CharField(max_length=50, blank=True)
address_line_1 = models.CharField(max_length=255, blank=True)
address_line_2 = models.CharField(max_length=255, blank=True)
city = models.CharField(max_length=100, blank=True)
postal_code = models.CharField(max_length=20, blank=True)
def get_formatted_address(self):
# Implement logic to format address based on country
if self.country == 'US':
return f'{self.address_line_1}\n{self.address_line_2}\n{self.city}, {self.postal_code}, {self.country}'
elif self.country == 'GB':
return f'{self.address_line_1}\n{self.address_line_2}\n{self.city}\n{self.postal_code}\n{self.country}'
else:
return 'Address format not supported'
4. é貨ć®å¦ē
ć¢ććŖć±ć¼ć·ć§ć³ćéčåå¼ć«é¢é£ććå “åćÆćć¦ć¼ć¶ć¼ć®åŖå é貨ćäæåććććć使ēØćć¦ä¾”ę ¼ćØéé”ć蔨示ćć¾ćć `babel`ćŖć©ć®ć©ć¤ćć©ćŖć使ēØćć¦ćć¦ć¼ć¶ć¼ć®ćć±ć¼ć«ć«å¾ć£ć¦é貨å¤ćęøå¼čØå®ćć¾ćć
ä¾ļ¼
from babel.numbers import format_currency
class CustomUser(AbstractUser):
#...
preferred_currency = models.CharField(max_length=3, default='USD')
def get_formatted_price(self, amount):
return format_currency(amount, self.preferred_currency, locale='en_US') # Adjust locale as needed
5. ćć¼ćæć®ę¤čؼ
å ē¢ćŖćć¼ćæę¤čؼćå®č£ ćć¦ćć¦ć¼ć¶ć¼å „åćęå¹ć§äøč²«ę§ćććććØć確čŖćć¾ćć Djangoć®ēµćæč¾¼ćæććŖćć¼ćæć¼ć使ēØććććć«ć¹ćæć ććŖćć¼ćæć¼ćä½ęćć¦ććć¼ćæę“åę§ćé©ēØćć¾ćć
ä¾ļ¼
from django.core.validators import RegexValidator
class CustomUser(AbstractUser):
#...
phone_number = models.CharField(
max_length=20,
blank=True,
validators=[
RegexValidator(
regex=r'^\+?\d{9,15}$',
message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed."
),
]
)
6. ć»ćć„ćŖćć£ć«é¢ććčę ®äŗé
ćć¹ćÆć¼ćć®ććć·ć„åļ¼ Djangoć®čŖčؼć·ć¹ćć ćÆćććć©ć«ćć§å¼·åćŖćć¹ćÆć¼ćććć·ć„åć¢ć«ć“ćŖćŗć ć使ēØćć¾ććęę°ćć¼ćøć§ć³ć®Djangoć使ēØćć¦ććććØć確čŖćć¦ćęę°ć®ć»ćć„ćŖćć£ć¢ćććć¼ććå©ēØćć¦ćć ććć
2č¦ē“ čŖčؼļ¼2FAļ¼ļ¼ 2FAćå®č£ ćć¦ćć¦ć¼ć¶ć¼ć¢ć«ć¦ć³ćć«ć»ćć„ćŖćć£ć®ć¬ć¤ć¤ć¼ćčæ½å ćć¾ććććć«ćÆć`django-otp`ćŖć©ććć¾ćć¾ćŖDjangoććć±ć¼ćøćēØęććć¦ćć¾ćććććÆćę©åÆę§ć®é«ćć¦ć¼ć¶ć¼ćć¼ćæćéčåå¼ćå¦ēććå “åć«ē¹ć«éč¦ć§ćć
ćć¼ćæäæč·ļ¼ ē¹ć«ę©åÆę§ć®é«ćć¦ć¼ć¶ć¼ę å ±ćę±ćå “åćÆććć¼ćæäæč·ćØćć©ć¤ćć·ć¼ć«é¢ćććć¹ććć©ćÆćć£ć¹ć«å¾ć£ć¦ćć ććć GDPRćCCPAćŖć©ć®é¢é£ćććć¼ćæäæč·č¦å¶ćéµå®ćć¦ćć ććććć¼ćæć®ęå·åćåæååćććć³ćć¼ćÆć³åć®ęę³ćę¤čØćć¦ćć ććć
7. ćć¹ć
å ę¬ēćŖć¦ććććć¹ććØēµ±åćć¹ććä½ęćć¦ćć«ć¹ćæć ć¦ć¼ć¶ć¼ć¢ćć«ćęå¾ ć©ććć«ę©č½ććčŖčؼć·ć¹ćć ćå®å Øć§ććććØć確čŖćć¾ććęå¹ććć³ē”å¹ćŖć¦ć¼ć¶ć¼å „åććć¹ćÆć¼ććŖć»ćććÆć¼ćÆććć¼ć権éćć§ććÆćŖć©ććć¾ćć¾ćŖć·ććŖćŖććć¹ććć¾ćć
8. ććć„ć”ć³ć
ć«ć¹ćæć ć¦ć¼ć¶ć¼ć¢ćć«ćØčŖčؼć·ć¹ćć ćå¾¹åŗēć«ęęøåćć¾ććććć«ćććä»ć®éēŗč ćć³ć¼ććēč§£ćć¦äæå®ćććććŖćć¾ććåćć£ć¼ć«ćć®ē®ēćčŖčؼććć¼ćććć³ć»ćć„ćŖćć£ć«é¢ććčę ®äŗé ć«é¢ććę å ±ćå«ćć¾ćć
é«åŗ¦ćŖććÆćććÆćØčę ®äŗé
1. ć«ć¹ćæć ć¦ć¼ć¶ć¼ććć¼ćøć£ć¼
`AbstractBaseUser`ć®ä¾ć§ē¤ŗććććć«ćć«ć¹ćæć ć¦ć¼ć¶ć¼ććć¼ćøć£ć¼ćÆć¦ć¼ć¶ć¼ć®ä½ęćØē®”ēć«äøåÆę¬ ć§ććē¹å®ć®ćć£ć¼ć«ćć«ććć©ć«ćå¤ćčØå®ććććčæ½å ć®ę¤čؼćå®č”ććććććŖć©ćć¦ć¼ć¶ć¼ćä½ęććććć®ć«ć¹ćæć ććøććÆćå®ē¾©ć§ćć¾ćć
2. ćććć·ć¢ćć«
ćććć·ć¢ćć«ć使ēØćććØććć¼ćæćć¼ć¹ć¹ćć¼ććå¤ę“ććć«ćć¦ć¼ć¶ć¼ć¢ćć«ć«ć”ć½ćććčæ½å ć§ćć¾ćććććÆćć¢ććŖć±ć¼ć·ć§ć³ć«åŗęć®ć«ć¹ćæć ććøććÆć¾ććÆčØē®ćčæ½å ććå “åć«å½¹ē«ć”ć¾ćć
3. ćććć£ć¼ć«ć¢ćć«ć使ēØććć¦ć¼ć¶ć¼ć¢ćć«ć®ę”å¼µ
å¤ćć®ćć£ć¼ć«ććć¦ć¼ć¶ć¼ć¢ćć«ć«ē“ę„čæ½å ćć代ććć«ćć¦ć¼ć¶ć¼ć¢ćć«ćØ1対1ć®é¢äæćęć¤åå„ć®ćććć£ć¼ć«ć¢ćć«ćä½ęć§ćć¾ćććććÆćć¦ć¼ć¶ć¼ć¢ćć«ććÆćŖć¼ć³ć§ę“ēćććē¶ę ć«äæć¤ć®ć«å½¹ē«ć”ć¾ćć
from django.db import models
from django.conf import settings
class UserProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='profile')
# Additional fields
bio = models.TextField(blank=True)
location = models.CharField(max_length=100, blank=True)
ć¦ć¼ć¶ć¼ćä½ęććććØćć«UserProfilećčŖåēć«ä½ęććć·ć°ćć«ćä½ęććććØćåæććŖćć§ćć ććć
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.conf import settings
from .models import UserProfile
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
4. ć·ć³ć°ć«ćµć¤ć³ćŖć³ļ¼SSOļ¼
大č¦ęØ”ćŖēµē¹ććä»ć®ćµć¼ćć¹ćØć®ēµ±åćåæ č¦ćŖć¢ććŖć±ć¼ć·ć§ć³ć®å “åćÆćOAuth 2.0ćSAMLćŖć©ć®ćććć³ć«ć使ēØćć¦ć·ć³ć°ć«ćµć¤ć³ćŖć³ļ¼SSOļ¼ć®å®č£ ćę¤čØćć¦ćć ććć Djangoć«ćÆćSSOć®ēµ±åćē°”ē“ åććććć¤ćć®ććć±ć¼ćøćēØęććć¦ćć¾ćļ¼`django-allauth`ćŖć©ļ¼ć
5. ē£ę»ćć°
ē£ę»ćć°ćå®č£ ćć¦ćć¦ć¼ć¶ć¼ć®ć¢ćÆćć£ććć£ćØć¦ć¼ć¶ć¼ćć¼ćæćøć®å¤ę“ć追跔ćć¾ćććććÆćć»ćć„ćŖćć£ē£č¦ćć³ć³ćć©ć¤ć¢ć³ć¹ćććć³ćććć°ć«å½¹ē«ć”ć¾ćć `django-auditlog`ćŖć©ć®ććć±ć¼ćøćÆććć®ććć»ć¹ćčŖååććć®ć«å½¹ē«ć”ć¾ćć
ēµč«
Djangoć§ć«ć¹ćæć ć¦ć¼ć¶ć¼ć¢ćć«ćä½ęććć³å®č£ ćććØćē¹ć«ć°ćć¼ćć«ć¢ććŖć±ć¼ć·ć§ć³ć®å “åćå ē¢ć§ć¹ć±ć¼ć©ćć«ćŖčŖčؼć·ć¹ćć ćę§ēÆććććć«åæ č¦ćŖęč»ę§ćØå¶å¾”ćå¾ććć¾ćććć®ć¬ć¤ćć§ę¦čŖ¬ććć¦ćććć¹ććć©ćÆćć£ć¹ć«å¾ćććØć§ćć¢ććŖć±ć¼ć·ć§ć³ćå¤ę§ćŖć¦ć¼ć¶ć¼č¦ä»¶ć«åƾåæćććć¼ćæę“åę§ćē¶ęććäøēäøć®ć¦ć¼ć¶ć¼ć«å®å Øć§ä½æćććććØćÆć¹ććŖćØć³ć¹ćęä¾ć§ććććć«ćŖćć¾ććå®č£ ćę éć«čØē»ććć¦ć¼ć¶ć¼ć®ćć¼ćŗćčę ®ććććć»ć¹ć®ćć¹ć¦ć®ę®µéć§ć»ćć„ćŖćć£ćåŖå ććććØćåæććŖćć§ćć ććć `AbstractBaseUser`ćØ`AbstractUser`ć®ć©ć”ććéøęććććÆćåæ č¦ćŖć«ć¹ćæćć¤ćŗć®ć¬ćć«ć«ćć£ć¦ē°ćŖćć¾ććå¤§å¹ ćŖå¤ę“ć®å “åćÆć`AbstractBaseUser`ć®ę¹ćå¶å¾”ć容ęć§ććē°”åćŖę”å¼µć®å “åćÆć`AbstractUser`ć®ę¹ćć¹ć ć¼ćŗć«ē§»č”ć§ćć¾ććć«ć¹ćæć ć¦ć¼ć¶ć¼ć¢ćć«ćDjangoć¢ććŖć±ć¼ć·ć§ć³ć®ä»ć®éØåćØć·ć¼ć ć¬ć¹ć«ēµ±åććććć¹ć¦ć®ć»ćć„ćŖćć£č¦ä»¶ćęŗććć¦ććććØć確čŖććć«ćÆćå¾¹åŗēćŖćć¹ććäøåÆę¬ ć§ććå½éåććć¼ć«ćŖć¼ć¼ć·ć§ć³ćććć³ćæć¤ć ć¾ć¼ć³ć®å¦ēć«é¢ćććć¹ććć©ćÆćć£ć¹ćę”ēØćć¦ćēć«ć°ćć¼ćć«ćŖćØćÆć¹ććŖćØć³ć¹ćęä¾ćć¾ććććć«ćććäøēäøć®å¤ę§ćŖåøå “ć«ćććć¢ććŖć±ć¼ć·ć§ć³ć®ęåćØę”ēØć«å¤§ććč²¢ē®ćć¾ćć